using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Amazon.ECS;
using Amazon.ECS.Query;
using Amazon.ECS.Model;
using System.Net;
using System.IO;

namespace DareMusicFixer
{
    #region Data
    struct AlbumKey
    {
        public AlbumKey(string artist, string album)
        {
            mArtist = artist;
            mAlbum = album;
        }

        public override bool Equals(object obj)
        {
            AlbumKey o = (AlbumKey)obj;
 	        return (mArtist == o.mArtist && mAlbum == o.mAlbum);
        }

        public override int  GetHashCode()
        {
 	        return base.GetHashCode();
        }

        public string mArtist;
        public string mAlbum;
    }
    #endregion

    public class AlbumArtGrabber
    {
        #region Private Variables
        String accessKeyId = "16QNRQV87R7AWA455102";
        String associateTag = "Your Associate Tag";

        static Dictionary<AlbumKey, byte[]> mImageCache = new Dictionary<AlbumKey, byte[]>();

        byte[] mImage;
        #endregion

        #region Constructor
        public AlbumArtGrabber()
        {
            mImage = null;            
        }
        #endregion

        #region Public Properties
        public byte[] Image
        {
            get { return mImage; }
        }
        #endregion

        #region Public Accessors
        public bool GrabCover(string artist, string album)
        {
            bool toReturn = true;

            if (!GetFromCache(artist, album, out mImage))
            {
                if (GrabCoverFromAmazon(artist, album))
                {
                    Log.WriteLine("Image Size: " + ImageHelpers.ImageSizeKB(mImage.Length, 2) + " KB");

                    if (ImageHelpers.ImageSizeKB(mImage.Length, 2) > 50.0f)
                    {
                        mImage = ImageHelpers.Scale(ImageHelpers.ByteArrayToImage(mImage), 200, 200);

                        Log.WriteLine("Resized to: " + ImageHelpers.ImageSizeKB(mImage.Length, 2) + " KB");
                    }

                    AddToCache(artist, album, mImage);
                    Log.WriteLine("Image Added to cache.");
                }
                else
                {
                    toReturn = false;
                }
            }
            else
            {
                Log.WriteLine("Found image in cache");
            }

            return toReturn;
        }
        #endregion

        #region Amazon Fetching
        private bool GrabCoverFromAmazon(string artist, string album)
        {
            AmazonECS service = new AmazonECSQuery(accessKeyId, associateTag);
            ItemSearchRequest request = new ItemSearchRequest();            
            request.SearchIndex = "Music";
            request.Artist = artist;
            request.Title = album;            
            List<string> responseGroups = new List<string>();
            responseGroups.Add("Images");
            request.ResponseGroup = responseGroups;

            Log.WriteLine("Grabbing Album...");

            try
            {
                ItemSearchResponse response = service.ItemSearch(request);
                
                List<Items> itemsList = response.Items;

                foreach (Items items in itemsList)
                {                    
                    List<Item> itemList = items.Item;

                    foreach (Item item in itemList)
                    {                        
                        Log.WriteLine(item.ASIN);                        
                        Log.WriteLine(item.LargeImage.URL);

                        byte[] buffer = new byte[4096];

                        WebRequest wr = WebRequest.Create(item.LargeImage.URL);

                        using (WebResponse wres = wr.GetResponse())
                        {
                            using (Stream responseStream = wres.GetResponseStream())
                            {
                                using (MemoryStream memoryStream = new MemoryStream())
                                {
                                    int count = 0;
                                    do
                                    {
                                        count = responseStream.Read(buffer, 0, buffer.Length);
                                        memoryStream.Write(buffer, 0, count);

                                    } while (count != 0);

                                    mImage = memoryStream.ToArray();
                                }
                            }
                        }

                        //mImage = System.Drawing.Image.FromStream(webResp.GetResponseStream());
                        return true;
                    }
                }
            }
            catch (Exception e)
            {
                Log.WriteLine(e.Message);
            }

            return false;
        }
        #endregion

        #region Cache Helpers
        private bool GetFromCache(string artist, string album, out byte[] image)
        {
            return mImageCache.TryGetValue(new AlbumKey(artist, album), out image);
        }

        private void AddToCache(string artist, string album, byte[] image)
        {
            mImageCache.Add(new AlbumKey(artist, album), image);
        }
        #endregion
    }
}
